package com.yzdbx.task;

import cn.hutool.core.collection.CollectionUtil;
import com.yzdbx.utils.DbUtil;
import com.yzdbx.utils.GenUtil;

import java.math.BigDecimal;
import java.sql.*;
import java.util.*;
import java.util.stream.Collectors;

import static com.yzdbx.task.SalefOrderRunnable.GEN_ORDER_IDS;
import static com.yzdbx.utils.DbUtil.getMaxId;

/**
 * @BelongsProject: SERVEVICE-DATA-GEN
 * @BelongsPackage: com.yzdbx.task
 * @Author: lk
 * @CreateTime: 2025-05-14
 * @Description: TODO
 * @Version: 1.0
 */
public class SaleOrderFaHuoRunnable implements Exe {

    private Connection connection;
    private static final int BATCH_SIZE = 3;
    private int batchCount = 0;

    public SaleOrderFaHuoRunnable(Connection connection) {
        this.connection = connection;
    }

    public static final ThreadLocal<List<Integer>> FAHUO_IDS = new ThreadLocal<List<Integer>>() {
        @Override
        protected List<Integer> initialValue() {
            return new ArrayList<Integer>();
        }
    };

    @Override
    public boolean execute(int count) {
        //拿到生成的销售订单明细
        List<Integer> orderIds = GEN_ORDER_IDS.get();
        if (CollectionUtil.isEmpty(orderIds)) return Boolean.FALSE;

        List<Integer> fahuoIds = new ArrayList<>(orderIds.size());
        boolean originalAutoCommit = true;
        
        // 按日期分组的出库单号计数器
        Map<String, Integer> ckDateCounterMap = new HashMap<>();

        try {
            // 保存原始自动提交状态
            originalAutoCommit = connection.getAutoCommit();
            connection.setAutoCommit(false);

            int fahuoMaxId = getMaxId(connection, "xs05SalesAndDispatch");
            int ckdId = getMaxId(connection, "lists");
            int maxDetailId = getMaxId(connection, "xssalesDispatchDetails");
            int ckmxId = getMaxId(connection, "ck02CheckoutFormCheckout");

            // 准备批量插入语句
            String detailSql = "insert into xssalesDispatchDetails (id,associatedConsignmentOrder,productInformation,quantityOfShipments,amountOfShipment,unitPriceForShipment,numberOfOrders,numberOfRemainingShipments,numberOfRefunds,amountOfReturn,synchronisingFolderFailedSS,modifyer) values (?,?,?,?,?,?,?,?,?,?,?,?)";
            String fahuoSql = "insert into xs05SalesAndDispatch (id,shipmentOrderNumber,dateOfShipment,shipper,associatedSalesOrders,clientInformation,quantityOfShipments,synchronisingFolderFailedSS,created,approvalStatus) values (?,?,?,?,?,?,?,?,?,?)";
            String ckmxSql = "insert into ck02CheckoutFormCheckout(id,productInformation,numberOfReleases,inventoryUnitPrice,numberOfDeposits,linkOutList,synchronisingFolderFailedSS,modifyer,created,modified) values (?,?,?,?,?,?,?,?,?,?)";
            String ckdSql = "insert into lists (id,cashiersNumber,poolType,collectionDate,operator,synchronisingFolderFailedSS,created,associatedOrders,clientInformation) values (?,?,?,?,?,?,?,?,?)";

            try (PreparedStatement detailStatement = connection.prepareStatement(detailSql);
                 PreparedStatement fahuoStatement = connection.prepareStatement(fahuoSql);
                 PreparedStatement ckmxStatement = connection.prepareStatement(ckmxSql);
                 PreparedStatement ckdStatement = connection.prepareStatement(ckdSql)) {


                for (int i = 1; i <= orderIds.size(); i++) {
                    final int currentIndex = i - 1;
                    int curId = fahuoMaxId + i;
                    String fahuodanhao = GenUtil.getNo("XSFH", i);
                    
                    //查询销售订单
                    Map<String, Object> saleOrder = DbUtil.getById(connection, "salesOrders", orderIds.get(currentIndex));
                    
                    //查询销售订单明细
                    List<LinkedHashMap<String, Object>> details;
                    try (PreparedStatement statement = connection.prepareStatement("select * from xs02SalesOrderBreakdown where associatedSalesOrders = ?")) {
                        statement.setInt(1, orderIds.get(currentIndex));
                        ResultSet resultSet = statement.executeQuery();
                        details = DbUtil.resultSetToList(resultSet);
                    }

                    List<LinkedHashMap<String, Object>> associatedSalesOrders = details.stream()
                            .filter(cur -> cur.get("associatedSalesOrders").equals(orderIds.get(currentIndex)))
                            .collect(Collectors.toList());

                    // 创建发货单详情
                    for (int j = 1; j <= associatedSalesOrders.size(); j++) {
                        int detailId = ++maxDetailId;
                        LinkedHashMap<String, Object> orderDetail = associatedSalesOrders.get(j - 1);
                        
                        detailStatement.setInt(1, detailId);
                        detailStatement.setInt(2, curId);
                        detailStatement.setInt(3, Integer.parseInt(orderDetail.get("productInformation").toString()));
                        detailStatement.setInt(4, Integer.parseInt(orderDetail.get("quantityOfShipments").toString()));
                        BigDecimal unitPrice = BigDecimal.valueOf(Double.parseDouble(orderDetail.get("unitPrice").toString()));
                        int quantity = Integer.parseInt(orderDetail.get("quantityOfShipments").toString());
                        detailStatement.setBigDecimal(5, unitPrice.multiply(BigDecimal.valueOf(quantity)).setScale(2, BigDecimal.ROUND_HALF_UP));
                        detailStatement.setBigDecimal(6, unitPrice);
                        detailStatement.setInt(7, quantity);
                        detailStatement.setInt(8, 0);
                        detailStatement.setInt(9, 0);
                        detailStatement.setInt(10, 0);
                        detailStatement.setString(11, saleOrder.get("synchronisingFolderFailedSS").toString());
                        detailStatement.setString(12, saleOrder.get("synchronisingFolderFailedSS").toString());
                        detailStatement.addBatch();

                        // 创建出库明细
                        int curCkmxId = ++ckmxId;
                        ckmxStatement.setInt(1, curCkmxId);
                        ckmxStatement.setInt(2, Integer.parseInt(orderDetail.get("productInformation").toString()));
                        ckmxStatement.setInt(3, quantity);
                        ckmxStatement.setBigDecimal(4, unitPrice);
                        ckmxStatement.setBigDecimal(5, unitPrice.multiply(BigDecimal.valueOf(quantity)).setScale(2, BigDecimal.ROUND_HALF_UP));
                        ckmxStatement.setInt(6, ckdId + i);
                        ckmxStatement.setString(7, saleOrder.get("synchronisingFolderFailedSS").toString());
                        ckmxStatement.setString(8, saleOrder.get("synchronisingFolderFailedSS").toString());
                        ckmxStatement.setTimestamp(9, GenUtil.CUR_TIME_STAMP.get());
                        ckmxStatement.setTimestamp(10, GenUtil.CUR_TIME_STAMP.get());
                        ckmxStatement.addBatch();
                    }

                    // 创建发货单
                    fahuoStatement.setInt(1, curId);
                    fahuoStatement.setString(2, fahuodanhao);
                    fahuoStatement.setTimestamp(3, GenUtil.CUR_TIME_STAMP.get());
                    fahuoStatement.setString(4, saleOrder.get("synchronisingFolderFailedSS").toString());
                    fahuoStatement.setInt(5, orderIds.get(currentIndex));
                    fahuoStatement.setInt(6, Integer.parseInt(saleOrder.get("clientInformation").toString()));
                    fahuoStatement.setInt(7, Integer.parseInt(saleOrder.get("numberOfOrders").toString()));
                    fahuoStatement.setString(8, saleOrder.get("synchronisingFolderFailedSS").toString());
                    fahuoStatement.setTimestamp(9, GenUtil.CUR_TIME_STAMP.get());
                    fahuoStatement.setString(10, "已通过");
                    fahuoStatement.addBatch();

                    // 按日期分组的出库单号生成逻辑
                    String dateKey = saleOrder.get("dateOfOrder").toString();
                    int ckCurrentCount = ckDateCounterMap.getOrDefault(dateKey, 0) + 1;
                    ckDateCounterMap.put(dateKey, ckCurrentCount);
                    
                    // 设置当前日期为订单日期，确保单号生成正确
                    java.sql.Date orderDate = (java.sql.Date) saleOrder.get("dateOfOrder");
                    GenUtil.setCurDate(orderDate.toLocalDate());
                    GenUtil.setCurTimeStamp(new Timestamp(orderDate.getTime()));
                    
                    // 创建出库单
                    ckdStatement.setInt(1, ckdId + i);
                    ckdStatement.setString(2, GenUtil.getNo("CK", ckCurrentCount));
                    ckdStatement.setString(3, "销售出库");
                    ckdStatement.setTimestamp(4, GenUtil.CUR_TIME_STAMP.get());
                    ckdStatement.setString(5, saleOrder.get("synchronisingFolderFailedSS").toString());
                    ckdStatement.setString(6, saleOrder.get("synchronisingFolderFailedSS").toString());
                    ckdStatement.setTimestamp(7, GenUtil.CUR_TIME_STAMP.get());
                    ckdStatement.setInt(8, orderIds.get(currentIndex));
                    ckdStatement.setInt(9, Integer.parseInt(saleOrder.get("clientInformation").toString()));
                    ckdStatement.addBatch();

                    fahuoIds.add(curId);
                    batchCount++;

                    // 每BATCH_SIZE条记录执行一次批量插入
                    if (batchCount >= BATCH_SIZE) {
                        detailStatement.executeBatch();
                        fahuoStatement.executeBatch();
                        ckmxStatement.executeBatch();
                        ckdStatement.executeBatch();
                        connection.commit();
                        batchCount = 0;
                    }
                }

                // 执行剩余的批量插入
                if (batchCount > 0 ) {
                    detailStatement.executeBatch();
                    fahuoStatement.executeBatch();
                    ckmxStatement.executeBatch();
                    ckdStatement.executeBatch();
                    connection.commit();
                }

            }

        } catch (Exception e) {
            try {
                if (!connection.getAutoCommit()) {
                    connection.rollback();
                }
            } catch (SQLException ex) {
                throw new RuntimeException("回滚失败", ex);
            }
            throw new RuntimeException("数据生成失败", e);
        } finally {
            try {
                // 恢复原始自动提交状态
                connection.setAutoCommit(originalAutoCommit);
            } catch (SQLException e) {
                throw new RuntimeException("恢复自动提交状态失败", e);
            }
        }

        FAHUO_IDS.set(fahuoIds);
        return Boolean.TRUE;
    }
}
